import type { ServerSetupFunc, WsHandler } from "../node/network";
import { __projectDir, getModules, handleWsClient } from "../node";
import { resolve } from "path";
import Express, { RequestHandler } from "express";

/**
 * 自动导入backend/server/websocket-apis
 * @example //backend/server/websocket-apis/**.ts
 * import { WsHandler } from "albert.gao/node/network";
 * let handle: WsHandler = {
 *  e: "message",
 *  func: ({ json, broadcast }) => {
 *    if (json.id) {
 *      broadcast(json);
 *    }
 *  },
 * };
 */
export function importWss(): WsHandler[] {
  return getModules(
    resolve(__projectDir, "backend.js/server/websocket-apis")
  ).map((e) => e.module.default as WsHandler);
}

/**
 * 自动导入backend/server/express-routers
 * @example //backend/server/express-routers/**.ts
 * import { Router } from "express";
 * let router = Router();
 * export const priority = 100; // priority: number, the bigger the priority, the earlier the router will be mounted. (default: 0)
 * export default router; // export anything that goes into Express().use()
 */
export async function importApi({
  app,
}: {
  app: Express.Express;
}): Promise<void> {
  type AppUse = RequestHandler | Promise<RequestHandler>;
  let modules = getModules(
    resolve(__projectDir, "backend.js/server/express-routers")
  ).map((e) => e.module.default as AppUse | AppUse[]);
  for (let mod0 of modules) {
    const _modRaw = await mod0;
    if (_modRaw instanceof Array) {
      for (let _modeFinal of _modRaw) {
        app.use(await _modeFinal);
      }
    } else {
      app.use(_modRaw);
    }
  }
}
/**
 * 自动导入backend/web-workers
 */
export function importWebWorkers({ app }: { app: Express.Express }): {} {
  app.use(
    "/web-workers",
    Express.static(resolve(__projectDir, "backend.js/web-workers"))
  );
  return {};
}

/**
 * @deprecated
 * 自动导入backend/server/websocket-apis、backend/server/express-routers、backend/web-workers
 * (vite-electron-express项目的默认配置)
 * @example //backend/server/express-routers/**.ts
 * import { Router } from "express";
 * let router = Router();
 * export const priority = 100; // priority: number, the bigger the priority, the earlier the router will be mounted. (default: 0)
 * export default router; // export anything that goes into Express().use()
 * @example //backend/server/websocket-apis/**.ts
 * import { WsHandler } from "albert.gao/node/network";
 * let handle: WsHandler = {
 *  e: "message",
 *  func: ({ json, broadcast }) => {
 *    if (json.id) {
 *      broadcast(json);
 *    }
 *  },
 * };
 * @param option
 * @returns
 */
export const autoImport: ServerSetupFunc = async ({ app, wss, broadcast }) => {
  importWebWorkers({ app });
  await importApi({ app });
  handleWsClient(
    [
      // @ts-ignore
      wss,
    ],
    broadcast,
    importWss()
  );
  return { app };
};

export default autoImport;
